﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Metropolitics.Source
{
    class City
    {
        #region Members

        private string name;
        private Vector2 position;
        private Vector2 dimensions;
        private List<char> cityleveltile;
        private List<char> tracklevel1tile;
        private List<char> tracklevel2tile;
        private List<int> citylevelcolor;
        private List<int> tracklevel1color;
        private List<int> tracklevel2color;
        private Texture2D cityleveltexture;
        private Texture2D tracklevel1texture;
        private Texture2D tracklevel2texture;
        private bool citylevelchanged;
        private bool tracklevel1changed;
        private bool tracklevel2changed;

        #endregion

        #region Properties

        public string Name
        {
            get
            {
                return name;
            }
        }

        public Vector2 Position
        {
            get
            {
                return position;
            }
        }

        public Vector2 Dimensions
        {
            get
            {
                return dimensions;
            }
        }

        public Texture2D CityLevelTexture
        {
            get
            {
                return cityleveltexture;
            }
            set
            {
                cityleveltexture = value;
            }
        }

        public Texture2D TrackLevel1Texture
        {
            get
            {
                return tracklevel1texture;
            }
            set
            {
                tracklevel1texture = value;
            }
        }

        public Texture2D TrackLevel2Texture
        {
            get
            {
                return tracklevel2texture;
            }
            set
            {
                tracklevel2texture = value;
            }
        }

        public bool CityLevelChanged
        {
            get
            {
                return citylevelchanged;
            }
        }

        public bool TrackLevel1Changed
        {
            get
            {
                return tracklevel1changed;
            }
        }

        public bool TrackLevel2Changed
        {
            get
            {
                return tracklevel1changed;
            }
        }

        #endregion

        #region Functions

        public City(string _name, Vector2 _position, Vector2 _dimensions, string _filename)
        {
            name = _name;
            position = _position;
            dimensions = _dimensions;
            citylevelchanged = true;
            tracklevel1changed = true;
            tracklevel2changed = true;

           
        }

        public char GetCityLevelTileValue(int _x, int _y)
        {
            if (_y * (int)dimensions.X + _x < cityleveltile.Count)
            {
                return cityleveltile[_y * (int)dimensions.X + _x];
            }
            return (char)0;
        }

        public void SetCityLevelTileValue(int _x, int _y, char _value)
        {
            if (_y * (int)dimensions.X + _x < cityleveltile.Count)
            {
                cityleveltile[_y * (int)dimensions.X + _x] = _value;
                citylevelchanged = true;
            }
        }

        public char GetTrackLevel1TileValue(int _x, int _y)
        {
            if (_y * (int)dimensions.X + _x < tracklevel1tile.Count)
            {
                return tracklevel1tile[_y * (int)dimensions.X + _x];
            }
            return (char)0;
        }

        public void SetTrackLevel1TileValue(int _x, int _y, char _value)
        {
            if (_y * (int)dimensions.X + _x < tracklevel1tile.Count)
            {
                tracklevel1tile[_y * (int)dimensions.X + _x] = _value;
                tracklevel1changed = true;
            }
        }

        public char GetTrackLevel2TileValue(int _x, int _y)
        {
            if (_y * (int)dimensions.X + _x < tracklevel2tile.Count)
            {
                return tracklevel2tile[_y * (int)dimensions.X + _x];
            }
            return (char)0;
        }

        public void SetTrackLevel2TileValue(int _x, int _y, char _value)
        {
            if (_y * (int)dimensions.X + _x < tracklevel2tile.Count)
            {
                tracklevel2tile[_y * (int)dimensions.X + _x] = _value;
                tracklevel2changed = true;
            }
        }

        public int GetCityLevelColorValue(int _x, int _y)
        {
            if (_y * (int)dimensions.X + _x < citylevelcolor.Count)
            {
                return citylevelcolor[_y * (int)dimensions.X + _x]; 
            }
            return 0;
        }

        public void GetCityLevelColorValue(int _x, int _y, ref byte _a, ref byte _r, ref byte _g, ref byte _b)
        {
            if (_y * (int)dimensions.X + _x < citylevelcolor.Count)
            {
                int i;
                int color = citylevelcolor[_y * (int)dimensions.X + _x];

                for (i = 0; i < 4; ++i)
                {
                    if ((int)(color & (4096 * (1 << i))) != 0)
                    {
                        _a |= (byte)(1 << i);
                    }
                }

                for (i = 0; i < 4; ++i)
                {
                    if ((int)(color & (256 * (1 << i))) != 0)
                    {
                        _r |= (byte)(1 << i);
                    }
                }

                for (i = 0; i < 4; ++i)
                {
                    if ((int)(color & (16 * (1 << i))) != 0)
                    {
                        _g |= (byte)(1 << i);
                    }
                }

                for (i = 0; i < 4; ++i)
                {
                    if ((int)(color & (1 << i)) != 0)
                    {
                        _b |= (byte)(1 << i);
                    }
                }
            }
        }

        public void SetCityLevelColorValue(int _x, int _y, int _value)
        {
            if (_y * (int)dimensions.X + _x < citylevelcolor.Count)
            {
                citylevelcolor[_y * (int)dimensions.X + _x] = _value;
                citylevelchanged = true;
            }
        }

        public int GetTrackLevel1ColorValue(int _x, int _y)
        {
            if (_y * (int)dimensions.X + _x < tracklevel1color.Count)
            {
                return tracklevel1color[_y + (int)dimensions.X + _x];
            }
            return 0;
        }

        public void GetTrackLevel1ColorValue(int _x, int _y, byte _a, byte _r, byte _g, byte _b)
        {
            if (_y * (int)dimensions.X + _x < tracklevel1color.Count)
            {
                int i;
                int color = tracklevel1color[_y * (int)dimensions.X + _x];

                for (i = 0; i < 4; ++i)
                {
                    if ((int)(color & (4096 * (1 << i))) != 0)
                    {
                        _a |= (byte)(1 << i);
                    }
                }

                for (i = 0; i < 4; ++i)
                {
                    if((int)(color & (256 * (1 << i))) != 0)
                    {
                        _r |= (byte)(1 << i);
                    }
                }

                for (i = 0; i < 4; ++i)
                {
                    if ((int)(color & (16 * (1 << i))) != 0)
                    {
                        _g |= (byte)(1 << i);
                    }
                }

                for (i = 0; i < 4; ++i)
                {
                    if ((int)(color & (1 << i)) != 0)
                    {
                        _b |= (byte)(1 << i);
                    }
                }
            }
        }

        public void SetTrackLevel1ColorValue(int _x, int _y, int _value)
        {
            if (_y + (int)dimensions.X + _x < tracklevel1color.Count)
            {
                tracklevel1color[_y + (int)dimensions.X + _x] = _value;
                citylevelchanged = true;
            }
        }

        public int GetTrackLevel2ColorValue(int _x, int _y)
        {
            if (_y * (int)dimensions.X + _x < tracklevel1color.Count)
            {
                return tracklevel1color[_y * (int)dimensions.X + _x];
            }
            return 0;
        }

        public void GetTrackLevel2ColorValue(int _x, int _y, byte _a, byte _r, byte _g, byte _b)
        {
            if (_y * (int)dimensions.X + _x < tracklevel1color.Count)
            {
                int i;
                int color = tracklevel1color[_y * (int)dimensions.X + _x];

                for (i = 0; i < 4; ++i)
                {
                    if ((int)(color & (4096 * (1 << i))) != 0)
                    {
                        _a |= (byte)(1 << i);
                    }
                }

                for (i = 0; i < 4; ++i)
                {
                    if ((int)(color & (256 * (1 << i))) != 0)
                    {
                        _r |= (byte)(1 << i);
                    }
                }

                for (i = 0; i < 4; ++i)
                {
                    if ((int)(color & (16 * (1 << i))) != 0)
                    {
                        _g |= (byte)(1 << i);
                    }
                }

                for (i = 0; i < 4; ++i)
                {
                    if ((int)(color & (1 << i)) != 0)
                    {
                        _b |= (byte)(1 << i);
                    } 
                }
            }
        }

        public void SetTrackLevel2ColorValue(int _x, int _y, int _value)
        {
            if (_y * (int)dimensions.X + _x < tracklevel2color.Count)
            {
                tracklevel2color[_y * (int)dimensions.X + _x] = _value;
                tracklevel2changed = true;
            }
        }

        #endregion
    }
}
